home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / draw.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  17KB  |  903 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20.  
  21. // draw.c -- this is the only file outside the refresh that touches the
  22. // vid buffer
  23.  
  24. #include "quakedef.h"
  25.  
  26. typedef struct {
  27.     vrect_t    rect;
  28.     int        width;
  29.     int        height;
  30.     byte    *ptexbytes;
  31.     int        rowbytes;
  32. } rectdesc_t;
  33.  
  34. static rectdesc_t    r_rectdesc;
  35.  
  36. byte        *draw_chars;                // 8*8 graphic characters
  37. qpic_t        *draw_disc;
  38. qpic_t        *draw_backtile;
  39.  
  40. //=============================================================================
  41. /* Support Routines */
  42.  
  43. typedef struct cachepic_s
  44. {
  45.     char        name[MAX_QPATH];
  46.     cache_user_t    cache;
  47. } cachepic_t;
  48.  
  49. #define    MAX_CACHED_PICS        128
  50. cachepic_t    menu_cachepics[MAX_CACHED_PICS];
  51. int            menu_numcachepics;
  52.  
  53.  
  54. qpic_t    *Draw_PicFromWad (char *name)
  55. {
  56.     return W_GetLumpName (name);
  57. }
  58.  
  59. /*
  60. ================
  61. Draw_CachePic
  62. ================
  63. */
  64. qpic_t    *Draw_CachePic (char *path)
  65. {
  66.     cachepic_t    *pic;
  67.     int            i;
  68.     qpic_t        *dat;
  69.     
  70.     for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
  71.         if (!strcmp (path, pic->name))
  72.             break;
  73.  
  74.     if (i == menu_numcachepics)
  75.     {
  76.         if (menu_numcachepics == MAX_CACHED_PICS)
  77.             Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
  78.         menu_numcachepics++;
  79.         strcpy (pic->name, path);
  80.     }
  81.  
  82.     dat = Cache_Check (&pic->cache);
  83.  
  84.     if (dat)
  85.         return dat;
  86.  
  87. //
  88. // load the pic from disk
  89. //
  90.     COM_LoadCacheFile (path, &pic->cache);
  91.     
  92.     dat = (qpic_t *)pic->cache.data;
  93.     if (!dat)
  94.     {
  95.         Sys_Error ("Draw_CachePic: failed to load %s", path);
  96.     }
  97.  
  98.     SwapPic (dat);
  99.  
  100.     return dat;
  101. }
  102.  
  103.  
  104.  
  105. /*
  106. ===============
  107. Draw_Init
  108. ===============
  109. */
  110. void Draw_Init (void)
  111. {
  112.     int        i;
  113.  
  114.     draw_chars = W_GetLumpName ("conchars");
  115.     draw_disc = W_GetLumpName ("disc");
  116.     draw_backtile = W_GetLumpName ("backtile");
  117.  
  118.     r_rectdesc.width = draw_backtile->width;
  119.     r_rectdesc.height = draw_backtile->height;
  120.     r_rectdesc.ptexbytes = draw_backtile->data;
  121.     r_rectdesc.rowbytes = draw_backtile->width;
  122. }
  123.  
  124.  
  125.  
  126. /*
  127. ================
  128. Draw_Character
  129.  
  130. Draws one 8*8 graphics character with 0 being transparent.
  131. It can be clipped to the top of the screen to allow the console to be
  132. smoothly scrolled off.
  133. ================
  134. */
  135. void Draw_Character (int x, int y, int num)
  136. {
  137.     byte            *dest;
  138.     byte            *source;
  139.     unsigned short    *pusdest;
  140.     int                drawline;    
  141.     int                row, col;
  142.  
  143.     num &= 255;
  144.     
  145.     if (y <= -8)
  146.         return;            // totally off screen
  147.  
  148. #ifdef PARANOID
  149.     if (y > vid.height - 8 || x < 0 || x > vid.width - 8)
  150.         Sys_Error ("Con_DrawCharacter: (%i, %i)", x, y);
  151.     if (num < 0 || num > 255)
  152.         Sys_Error ("Con_DrawCharacter: char %i", num);
  153. #endif
  154.  
  155.     row = num>>4;
  156.     col = num&15;
  157.     source = draw_chars + (row<<10) + (col<<3);
  158.  
  159.     if (y < 0)
  160.     {    // clipped
  161.         drawline = 8 + y;
  162.         source -= 128*y;
  163.         y = 0;
  164.     }
  165.     else
  166.         drawline = 8;
  167.  
  168.  
  169.     if (r_pixbytes == 1)
  170.     {
  171.         dest = vid.conbuffer + y*vid.conrowbytes + x;
  172.     
  173.         while (drawline--)
  174.         {
  175.             if (source[0])
  176.                 dest[0] = source[0];
  177.             if (source[1])
  178.                 dest[1] = source[1];
  179.             if (source[2])
  180.                 dest[2] = source[2];
  181.             if (source[3])
  182.                 dest[3] = source[3];
  183.             if (source[4])
  184.                 dest[4] = source[4];
  185.             if (source[5])
  186.                 dest[5] = source[5];
  187.             if (source[6])
  188.                 dest[6] = source[6];
  189.             if (source[7])
  190.                 dest[7] = source[7];
  191.             source += 128;
  192.             dest += vid.conrowbytes;
  193.         }
  194.     }
  195.     else
  196.     {
  197.     // FIXME: pre-expand to native format?
  198.         pusdest = (unsigned short *)
  199.                 ((byte *)vid.conbuffer + y*vid.conrowbytes + (x<<1));
  200.  
  201.         while (drawline--)
  202.         {
  203.             if (source[0])
  204.                 pusdest[0] = d_8to16table[source[0]];
  205.             if (source[1])
  206.                 pusdest[1] = d_8to16table[source[1]];
  207.             if (source[2])
  208.                 pusdest[2] = d_8to16table[source[2]];
  209.             if (source[3])
  210.                 pusdest[3] = d_8to16table[source[3]];
  211.             if (source[4])
  212.                 pusdest[4] = d_8to16table[source[4]];
  213.             if (source[5])
  214.                 pusdest[5] = d_8to16table[source[5]];
  215.             if (source[6])
  216.                 pusdest[6] = d_8to16table[source[6]];
  217.             if (source[7])
  218.                 pusdest[7] = d_8to16table[source[7]];
  219.  
  220.             source += 128;
  221.             pusdest += (vid.conrowbytes >> 1);
  222.         }
  223.     }
  224. }
  225.  
  226. /*
  227. ================
  228. Draw_String
  229. ================
  230. */
  231. void Draw_String (int x, int y, char *str)
  232. {
  233.     while (*str)
  234.     {
  235.         Draw_Character (x, y, *str);
  236.         str++;
  237.         x += 8;
  238.     }
  239. }
  240.  
  241. /*
  242. ================
  243. Draw_DebugChar
  244.  
  245. Draws a single character directly to the upper right corner of the screen.
  246. This is for debugging lockups by drawing different chars in different parts
  247. of the code.
  248. ================
  249. */
  250. void Draw_DebugChar (char num)
  251. {
  252.     byte            *dest;
  253.     byte            *source;
  254.     int                drawline;    
  255.     extern byte        *draw_chars;
  256.     int                row, col;
  257.  
  258.     if (!vid.direct)
  259.         return;        // don't have direct FB access, so no debugchars...
  260.  
  261.     drawline = 8;
  262.  
  263.     row = num>>4;
  264.     col = num&15;
  265.     source = draw_chars + (row<<10) + (col<<3);
  266.  
  267.     dest = vid.direct + 312;
  268.  
  269.     while (drawline--)
  270.     {
  271.         dest[0] = source[0];
  272.         dest[1] = source[1];
  273.         dest[2] = source[2];
  274.         dest[3] = source[3];
  275.         dest[4] = source[4];
  276.         dest[5] = source[5];
  277.         dest[6] = source[6];
  278.         dest[7] = source[7];
  279.         source += 128;
  280.         dest += 320;
  281.     }
  282. }
  283.  
  284. /*
  285. =============
  286. Draw_Pic
  287. =============
  288. */
  289. void Draw_Pic (int x, int y, qpic_t *pic)
  290. {
  291.     byte            *dest, *source;
  292.     unsigned short    *pusdest;
  293.     int                v, u;
  294.  
  295.     if ((x < 0) ||
  296.         (x + pic->width > vid.width) ||
  297.         (y < 0) ||
  298.         (y + pic->height > vid.height))
  299.     {
  300.         Sys_Error ("Draw_Pic: bad coordinates");
  301.     }
  302.  
  303.     source = pic->data;
  304.  
  305.     if (r_pixbytes == 1)
  306.     {
  307.         dest = vid.buffer + y * vid.rowbytes + x;
  308.  
  309.         for (v=0 ; v<pic->height ; v++)
  310.         {
  311.             Q_memcpy (dest, source, pic->width);
  312.             dest += vid.rowbytes;
  313.             source += pic->width;
  314.         }
  315.     }
  316.     else
  317.     {
  318.     // FIXME: pretranslate at load time?
  319.         pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
  320.  
  321.         for (v=0 ; v<pic->height ; v++)
  322.         {
  323.             for (u=0 ; u<pic->width ; u++)
  324.             {
  325.                 pusdest[u] = d_8to16table[source[u]];
  326.             }
  327.  
  328.             pusdest += vid.rowbytes >> 1;
  329.             source += pic->width;
  330.         }
  331.     }
  332. }
  333.  
  334.  
  335. /*
  336. =============
  337. Draw_TransPic
  338. =============
  339. */
  340. void Draw_TransPic (int x, int y, qpic_t *pic)
  341. {
  342.     byte    *dest, *source, tbyte;
  343.     unsigned short    *pusdest;
  344.     int                v, u;
  345.  
  346.     if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
  347.          (unsigned)(y + pic->height) > vid.height)
  348.     {
  349.         Sys_Error ("Draw_TransPic: bad coordinates");
  350.     }
  351.         
  352.     source = pic->data;
  353.  
  354.     if (r_pixbytes == 1)
  355.     {
  356.         dest = vid.buffer + y * vid.rowbytes + x;
  357.  
  358.         if (pic->width & 7)
  359.         {    // general
  360.             for (v=0 ; v<pic->height ; v++)
  361.             {
  362.                 for (u=0 ; u<pic->width ; u++)
  363.                     if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
  364.                         dest[u] = tbyte;
  365.     
  366.                 dest += vid.rowbytes;
  367.                 source += pic->width;
  368.             }
  369.         }
  370.         else
  371.         {    // unwound
  372.             for (v=0 ; v<pic->height ; v++)
  373.             {
  374.                 for (u=0 ; u<pic->width ; u+=8)
  375.                 {
  376.                     if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
  377.                         dest[u] = tbyte;
  378.                     if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
  379.                         dest[u+1] = tbyte;
  380.                     if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
  381.                         dest[u+2] = tbyte;
  382.                     if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
  383.                         dest[u+3] = tbyte;
  384.                     if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
  385.                         dest[u+4] = tbyte;
  386.                     if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
  387.                         dest[u+5] = tbyte;
  388.                     if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
  389.                         dest[u+6] = tbyte;
  390.                     if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
  391.                         dest[u+7] = tbyte;
  392.                 }
  393.                 dest += vid.rowbytes;
  394.                 source += pic->width;
  395.             }
  396.         }
  397.     }
  398.     else
  399.     {
  400.     // FIXME: pretranslate at load time?
  401.         pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
  402.  
  403.         for (v=0 ; v<pic->height ; v++)
  404.         {
  405.             for (u=0 ; u<pic->width ; u++)
  406.             {
  407.                 tbyte = source[u];
  408.  
  409.                 if (tbyte != TRANSPARENT_COLOR)
  410.                 {
  411.                     pusdest[u] = d_8to16table[tbyte];
  412.                 }
  413.             }
  414.  
  415.             pusdest += vid.rowbytes >> 1;
  416.             source += pic->width;
  417.         }
  418.     }
  419. }
  420.  
  421.  
  422. /*
  423. =============
  424. Draw_TransPicTranslate
  425. =============
  426. */
  427. void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation)
  428. {
  429.     byte    *dest, *source, tbyte;
  430.     unsigned short    *pusdest;
  431.     int                v, u;
  432.  
  433.     if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
  434.          (unsigned)(y + pic->height) > vid.height)
  435.     {
  436.         Sys_Error ("Draw_TransPic: bad coordinates");
  437.     }
  438.         
  439.     source = pic->data;
  440.  
  441.     if (r_pixbytes == 1)
  442.     {
  443.         dest = vid.buffer + y * vid.rowbytes + x;
  444.  
  445.         if (pic->width & 7)
  446.         {    // general
  447.             for (v=0 ; v<pic->height ; v++)
  448.             {
  449.                 for (u=0 ; u<pic->width ; u++)
  450.                     if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
  451.                         dest[u] = translation[tbyte];
  452.  
  453.                 dest += vid.rowbytes;
  454.                 source += pic->width;
  455.             }
  456.         }
  457.         else
  458.         {    // unwound
  459.             for (v=0 ; v<pic->height ; v++)
  460.             {
  461.                 for (u=0 ; u<pic->width ; u+=8)
  462.                 {
  463.                     if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
  464.                         dest[u] = translation[tbyte];
  465.                     if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
  466.                         dest[u+1] = translation[tbyte];
  467.                     if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
  468.                         dest[u+2] = translation[tbyte];
  469.                     if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
  470.                         dest[u+3] = translation[tbyte];
  471.                     if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
  472.                         dest[u+4] = translation[tbyte];
  473.                     if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
  474.                         dest[u+5] = translation[tbyte];
  475.                     if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
  476.                         dest[u+6] = translation[tbyte];
  477.                     if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
  478.                         dest[u+7] = translation[tbyte];
  479.                 }
  480.                 dest += vid.rowbytes;
  481.                 source += pic->width;
  482.             }
  483.         }
  484.     }
  485.     else
  486.     {
  487.     // FIXME: pretranslate at load time?
  488.         pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
  489.  
  490.         for (v=0 ; v<pic->height ; v++)
  491.         {
  492.             for (u=0 ; u<pic->width ; u++)
  493.             {
  494.                 tbyte = source[u];
  495.  
  496.                 if (tbyte != TRANSPARENT_COLOR)
  497.                 {
  498.                     pusdest[u] = d_8to16table[tbyte];
  499.                 }
  500.             }
  501.  
  502.             pusdest += vid.rowbytes >> 1;
  503.             source += pic->width;
  504.         }
  505.     }
  506. }
  507.  
  508.  
  509. void Draw_CharToConback (int num, byte *dest)
  510. {
  511.     int        row, col;
  512.     byte    *source;
  513.     int        drawline;
  514.     int        x;
  515.  
  516.     row = num>>4;
  517.     col = num&15;
  518.     source = draw_chars + (row<<10) + (col<<3);
  519.  
  520.     drawline = 8;
  521.  
  522.     while (drawline--)
  523.     {
  524.         for (x=0 ; x<8 ; x++)
  525.             if (source[x])
  526.                 dest[x] = 0x60 + source[x];
  527.         source += 128;
  528.         dest += 320;
  529.     }
  530.  
  531. }
  532.  
  533. /*
  534. ================
  535. Draw_ConsoleBackground
  536.  
  537. ================
  538. */
  539. void Draw_ConsoleBackground (int lines)
  540. {
  541.     int                x, y, v;
  542.     byte            *src, *dest;
  543.     unsigned short    *pusdest;
  544.     int                f, fstep;
  545.     qpic_t            *conback;
  546.     char            ver[100];
  547.  
  548.     conback = Draw_CachePic ("gfx/conback.lmp");
  549.  
  550. // hack the version number directly into the pic
  551. #ifdef _WIN32
  552.     sprintf (ver, "(WinQuake) %4.2f", (float)VERSION);
  553.     dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver);
  554. #elif defined(X11)
  555.     sprintf (ver, "(X11 Quake %2.2f) %4.2f", (float)X11_VERSION, (float)VERSION);
  556.     dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver);
  557. #elif defined(__linux__)
  558.     sprintf (ver, "(Linux Quake %2.2f) %4.2f", (float)LINUX_VERSION, (float)VERSION);
  559.     dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver);
  560. #else
  561.     dest = conback->data + 320 - 43 + 320*186;
  562.     sprintf (ver, "%4.2f", VERSION);
  563. #endif
  564.  
  565.     for (x=0 ; x<strlen(ver) ; x++)
  566.         Draw_CharToConback (ver[x], dest+(x<<3));
  567.     
  568. // draw the pic
  569.     if (r_pixbytes == 1)
  570.     {
  571.         dest = vid.conbuffer;
  572.  
  573.         for (y=0 ; y<lines ; y++, dest += vid.conrowbytes)
  574.         {
  575.             v = (vid.conheight - lines + y)*200/vid.conheight;
  576.             src = conback->data + v*320;
  577.             if (vid.conwidth == 320)
  578.                 memcpy (dest, src, vid.conwidth);
  579.             else
  580.             {
  581.                 f = 0;
  582.                 fstep = 320*0x10000/vid.conwidth;
  583.                 for (x=0 ; x<vid.conwidth ; x+=4)
  584.                 {
  585.                     dest[x] = src[f>>16];
  586.                     f += fstep;
  587.                     dest[x+1] = src[f>>16];
  588.                     f += fstep;
  589.                     dest[x+2] = src[f>>16];
  590.                     f += fstep;
  591.                     dest[x+3] = src[f>>16];
  592.                     f += fstep;
  593.                 }
  594.             }
  595.         }
  596.     }
  597.     else
  598.     {
  599.         pusdest = (unsigned short *)vid.conbuffer;
  600.  
  601.         for (y=0 ; y<lines ; y++, pusdest += (vid.conrowbytes >> 1))
  602.         {
  603.         // FIXME: pre-expand to native format?
  604.         // FIXME: does the endian switching go away in production?
  605.             v = (vid.conheight - lines + y)*200/vid.conheight;
  606.             src = conback->data + v*320;
  607.             f = 0;
  608.             fstep = 320*0x10000/vid.conwidth;
  609.             for (x=0 ; x<vid.conwidth ; x+=4)
  610.             {
  611.                 pusdest[x] = d_8to16table[src[f>>16]];
  612.                 f += fstep;
  613.                 pusdest[x+1] = d_8to16table[src[f>>16]];
  614.                 f += fstep;
  615.                 pusdest[x+2] = d_8to16table[src[f>>16]];
  616.                 f += fstep;
  617.                 pusdest[x+3] = d_8to16table[src[f>>16]];
  618.                 f += fstep;
  619.             }
  620.         }
  621.     }
  622. }
  623.  
  624.  
  625. /*
  626. ==============
  627. R_DrawRect8
  628. ==============
  629. */
  630. void R_DrawRect8 (vrect_t *prect, int rowbytes, byte *psrc,
  631.     int transparent)
  632. {
  633.     byte    t;
  634.     int        i, j, srcdelta, destdelta;
  635.     byte    *pdest;
  636.  
  637.     pdest = vid.buffer + (prect->y * vid.rowbytes) + prect->x;
  638.  
  639.     srcdelta = rowbytes - prect->width;
  640.     destdelta = vid.rowbytes - prect->width;
  641.  
  642.     if (transparent)
  643.     {
  644.         for (i=0 ; i<prect->height ; i++)
  645.         {
  646.             for (j=0 ; j<prect->width ; j++)
  647.             {
  648.                 t = *psrc;
  649.                 if (t != TRANSPARENT_COLOR)
  650.                 {
  651.                     *pdest = t;
  652.                 }
  653.  
  654.                 psrc++;
  655.                 pdest++;
  656.             }
  657.  
  658.             psrc += srcdelta;
  659.             pdest += destdelta;
  660.         }
  661.     }
  662.     else
  663.     {
  664.         for (i=0 ; i<prect->height ; i++)
  665.         {
  666.             memcpy (pdest, psrc, prect->width);
  667.             psrc += rowbytes;
  668.             pdest += vid.rowbytes;
  669.         }
  670.     }
  671. }
  672.  
  673.  
  674. /*
  675. ==============
  676. R_DrawRect16
  677. ==============
  678. */
  679. void R_DrawRect16 (vrect_t *prect, int rowbytes, byte *psrc,
  680.     int transparent)
  681. {
  682.     byte            t;
  683.     int                i, j, srcdelta, destdelta;
  684.     unsigned short    *pdest;
  685.  
  686. // FIXME: would it be better to pre-expand native-format versions?
  687.  
  688.     pdest = (unsigned short *)vid.buffer +
  689.             (prect->y * (vid.rowbytes >> 1)) + prect->x;
  690.  
  691.     srcdelta = rowbytes - prect->width;
  692.     destdelta = (vid.rowbytes >> 1) - prect->width;
  693.  
  694.     if (transparent)
  695.     {
  696.         for (i=0 ; i<prect->height ; i++)
  697.         {
  698.             for (j=0 ; j<prect->width ; j++)
  699.             {
  700.                 t = *psrc;
  701.                 if (t != TRANSPARENT_COLOR)
  702.                 {
  703.                     *pdest = d_8to16table[t];
  704.                 }
  705.  
  706.                 psrc++;
  707.                 pdest++;
  708.             }
  709.  
  710.             psrc += srcdelta;
  711.             pdest += destdelta;
  712.         }
  713.     }
  714.     else
  715.     {
  716.         for (i=0 ; i<prect->height ; i++)
  717.         {
  718.             for (j=0 ; j<prect->width ; j++)
  719.             {
  720.                 *pdest = d_8to16table[*psrc];
  721.                 psrc++;
  722.                 pdest++;
  723.             }
  724.  
  725.             psrc += srcdelta;
  726.             pdest += destdelta;
  727.         }
  728.     }
  729. }
  730.  
  731.  
  732. /*
  733. =============
  734. Draw_TileClear
  735.  
  736. This repeats a 64*64 tile graphic to fill the screen around a sized down
  737. refresh window.
  738. =============
  739. */
  740. void Draw_TileClear (int x, int y, int w, int h)
  741. {
  742.     int                width, height, tileoffsetx, tileoffsety;
  743.     byte            *psrc;
  744.     vrect_t            vr;
  745.  
  746.     r_rectdesc.rect.x = x;
  747.     r_rectdesc.rect.y = y;
  748.     r_rectdesc.rect.width = w;
  749.     r_rectdesc.rect.height = h;
  750.  
  751.     vr.y = r_rectdesc.rect.y;
  752.     height = r_rectdesc.rect.height;
  753.  
  754.     tileoffsety = vr.y % r_rectdesc.height;
  755.  
  756.     while (height > 0)
  757.     {
  758.         vr.x = r_rectdesc.rect.x;
  759.         width = r_rectdesc.rect.width;
  760.  
  761.         if (tileoffsety != 0)
  762.             vr.height = r_rectdesc.height - tileoffsety;
  763.         else
  764.             vr.height = r_rectdesc.height;
  765.  
  766.         if (vr.height > height)
  767.             vr.height = height;
  768.  
  769.         tileoffsetx = vr.x % r_rectdesc.width;
  770.  
  771.         while (width > 0)
  772.         {
  773.             if (tileoffsetx != 0)
  774.                 vr.width = r_rectdesc.width - tileoffsetx;
  775.             else
  776.                 vr.width = r_rectdesc.width;
  777.  
  778.             if (vr.width > width)
  779.                 vr.width = width;
  780.  
  781.             psrc = r_rectdesc.ptexbytes +
  782.                     (tileoffsety * r_rectdesc.rowbytes) + tileoffsetx;
  783.  
  784.             if (r_pixbytes == 1)
  785.             {
  786.                 R_DrawRect8 (&vr, r_rectdesc.rowbytes, psrc, 0);
  787.             }
  788.             else
  789.             {
  790.                 R_DrawRect16 (&vr, r_rectdesc.rowbytes, psrc, 0);
  791.             }
  792.  
  793.             vr.x += vr.width;
  794.             width -= vr.width;
  795.             tileoffsetx = 0;    // only the left tile can be left-clipped
  796.         }
  797.  
  798.         vr.y += vr.height;
  799.         height -= vr.height;
  800.         tileoffsety = 0;        // only the top tile can be top-clipped
  801.     }
  802. }
  803.  
  804.  
  805. /*
  806. =============
  807. Draw_Fill
  808.  
  809. Fills a box of pixels with a single color
  810. =============
  811. */
  812. void Draw_Fill (int x, int y, int w, int h, int c)
  813. {
  814.     byte            *dest;
  815.     unsigned short    *pusdest;
  816.     unsigned        uc;
  817.     int                u, v;
  818.  
  819.     if (r_pixbytes == 1)
  820.     {
  821.         dest = vid.buffer + y*vid.rowbytes + x;
  822.         for (v=0 ; v<h ; v++, dest += vid.rowbytes)
  823.             for (u=0 ; u<w ; u++)
  824.                 dest[u] = c;
  825.     }
  826.     else
  827.     {
  828.         uc = d_8to16table[c];
  829.  
  830.         pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
  831.         for (v=0 ; v<h ; v++, pusdest += (vid.rowbytes >> 1))
  832.             for (u=0 ; u<w ; u++)
  833.                 pusdest[u] = uc;
  834.     }
  835. }
  836. //=============================================================================
  837.  
  838. /*
  839. ================
  840. Draw_FadeScreen
  841.  
  842. ================
  843. */
  844. void Draw_FadeScreen (void)
  845. {
  846.     int            x,y;
  847.     byte        *pbuf;
  848.  
  849.     VID_UnlockBuffer ();
  850.     S_ExtraUpdate ();
  851.     VID_LockBuffer ();
  852.  
  853.     for (y=0 ; y<vid.height ; y++)
  854.     {
  855.         int    t;
  856.  
  857.         pbuf = (byte *)(vid.buffer + vid.rowbytes*y);
  858.         t = (y & 1) << 1;
  859.  
  860.         for (x=0 ; x<vid.width ; x++)
  861.         {
  862.             if ((x & 3) != t)
  863.                 pbuf[x] = 0;
  864.         }
  865.     }
  866.  
  867.     VID_UnlockBuffer ();
  868.     S_ExtraUpdate ();
  869.     VID_LockBuffer ();
  870. }
  871.  
  872. //=============================================================================
  873.  
  874. /*
  875. ================
  876. Draw_BeginDisc
  877.  
  878. Draws the little blue disc in the corner of the screen.
  879. Call before beginning any disc IO.
  880. ================
  881. */
  882. void Draw_BeginDisc (void)
  883. {
  884.  
  885.     D_BeginDirectRect (vid.width - 24, 0, draw_disc->data, 24, 24);
  886. }
  887.  
  888.  
  889. /*
  890. ================
  891. Draw_EndDisc
  892.  
  893. Erases the disc icon.
  894. Call after completing any disc IO
  895. ================
  896. */
  897. void Draw_EndDisc (void)
  898. {
  899.  
  900.     D_EndDirectRect (vid.width - 24, 0, 24, 24);
  901. }
  902.  
  903.